/**************************************************************************************
*  LEDSwing.java
*  Demo program for controlling the LEDs on LPC21xx.
**************************************************************************************
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL RTJ COMPUTING BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Created by:
*      RTJ Computing
**************************************************************************************/
import lpc2xxx.hw.*;
import lpc2xxx.comm.*;

class LEDSwing
{
    static int ledSpeed = 50;
    static boolean exit = false;
    static final int ALL_LED = 0x0000FF00;
    static final int LED1 = 0x00000100;
    static final int LED4 = 0x00000800;
    static final int LED5 = 0x00001000;
    static final int LED8 = 0x00008000;
    static GPIO p0 = new GPIO(GPIO.PORT0);

    static void main(String[] args)
    {
        GPIO.config(0, 0x0000FFFF, 0);
        p0.dirOut(0x0000FF00);
        p0.set(ALL_LED);
        
        Console.println("\r\nLED Swing program for Embedded Artists LPC2148 Education board.");
        Console.println("Jumper settings:");
        Console.println("  disconnect J49,J51,J53");
        Console.println("  connect    J43,J44,J46,J47,J48,J50,J52,J54\r\n");
        Console.println("Use ',' and '.' to increase/decrease swing period.");
        Console.println("Use space bar to cycle through swing patterns.");
        Console.println("Press ENTER to start, ESC to exit.");
        while (true)
        {
            int ch = Console.getKey();
            if (ch == 0x1B)
                return;
            else if (ch == 0x0D)
                break;
        }

        boolean again = false;
        int pattern = 1;
        int loopCount = 0;
        while (true)
        {
            if (exit)
                break;

            switch (pattern)
            {
                case 1:
                    again = swingPattern1(!again);
                    break;
                case 2:
                    again = swingPattern2(!again);
                    break;
                case 3:
                    again = swingPattern3(!again);
                    break;
                case 4:
                    again = swingPattern4(!again);
                    break;
                case 5:
                    again = swingPattern5(!again);
                    break;
                case 6:
                    again = swingPattern6(!again);
                    break;
            }
            if (!again)
            {
                pattern++;
                if (pattern > 6)
                    pattern = 1;
            }
            Console.print("\rSpeed: " + ledSpeed + "ms, Loops: " + loopCount++);
        }
    }

    static boolean changeSpeed()
    {
        if (Console.keyAvail())
        {
            char ch = Console.getKey();
            switch (ch)
            {
                case '.':
                    if (ledSpeed > 10)
                        ledSpeed -= ledSpeed > 75 ? 5 : 1;
                    break;

                case ',':
                    if (ledSpeed < 200)
                        ledSpeed += ledSpeed > 75 ? 5 : 1;
                    break;

                case Console.ESC:
                    exit = true;

                case ' ':
                    return false;
            }
        }
        return true;
    }

    static boolean swingPattern1(boolean change)
    {
        if (change)
            p0.set(ALL_LED);

        for (int i=LED1; i <= LED8; i <<= 1)
        {
            if (!changeSpeed())
                return false;
            p0.clear(i);
            sleep();
            p0.set(i);
        }
        for (int i=LED8; i >= LED1; i >>= 1)
        {
            if (!changeSpeed())
                return false;
            p0.clear(i);
            sleep();
            p0.set(i);
        }
        return true;
    }

    static boolean swingPattern2(boolean change)
    {
        if (change)
            p0.clear(ALL_LED);

        for (int i=LED1; i <= LED8; i <<= 1)
        {
            if (!changeSpeed())
                return false;
            p0.set(i);
            sleep();
            p0.clear(i);
        }
        for (int i=LED8; i >= LED1; i >>= 1)
        {
            if (!changeSpeed())
                return false;
            p0.set(i);
            sleep();
            p0.clear(i);
        }
        return true;
    }

    static boolean swingPattern3(boolean change)
    {
        if (change)
            p0.set(ALL_LED);

        for (int i=LED1; i <= LED8; i <<= 1)
        {
            if (!changeSpeed())
                return false;
            p0.clear(i);
            sleep();
        }
        for (int i=LED1; i <= LED8; i <<= 1)
        {
            if (!changeSpeed())
                return false;
            p0.set(i);
            sleep();
        }
        for (int i=LED8; i >= LED1; i >>= 1)
        {
            if (!changeSpeed())
                return false;
            p0.clear(i);
            sleep();
        }
        for (int i=LED8; i >= LED1; i >>= 1)
        {
            if (!changeSpeed())
                return false;
            p0.set(i);
            sleep();
        }
        return true;
    }

    static boolean swingPattern4(boolean change)
    {
        if (change)
            p0.set(ALL_LED);

        for (int i=LED1, j=LED8 ; i <= LED8; i <<= 1, j >>= 1)
        {
            if (!changeSpeed())
                return false;
            p0.clear(i);
            p0.clear(j);
            sleep();
            p0.set(i);
            p0.set(j);
        }
        return true;
    }

    static boolean swingPattern5(boolean change)
    {
        if (change)
            p0.set(ALL_LED);

        for (int i=LED1, j=LED8 ; i <= LED4; i <<= 1, j >>= 1)
        {
            if (!changeSpeed())
                return false;
            p0.clear(i);
            p0.clear(j);
            sleep();
        }
        for (int i=LED1, j=LED8 ; i <= LED4; i <<= 1, j >>= 1)
        {
            if (!changeSpeed())
                return false;
            p0.set(i);
            p0.set(j);
            sleep();
        }
        for (int i=LED4, j=LED5 ; i <= LED8; i <<= 1, j >>= 1)
        {
            if (!changeSpeed())
                return false;
            p0.clear(i);
            p0.clear(j);
            sleep();
        }
        for (int i=LED4, j=LED5 ; i <= LED8; i <<= 1, j >>= 1)
        {
            if (!changeSpeed())
                return false;
            p0.set(i);
            p0.set(j);
            sleep();
        }
        return true;
    }
    
    static boolean swingPattern6(boolean change)
    {
        if (change)
            p0.set(ALL_LED);

        int prevLedSpeed = ledSpeed;
        ledSpeed = 150;
        int pat[] = { 0x00005500, 0x00003300, 0x00000F00, 0x0000F000 };
        try 
        {
            for (int i=0; i < pat.length; i++)
            {
                for (int j=0; j < 10; j++)
                {
                    if (!changeSpeed())
                        return false;
                    p0.clear(pat[i]);
                    sleep();
                    p0.set(pat[i]);
                    p0.clear(~pat[i]);
                    sleep();
                    p0.set (~pat[i]);
                }
            }
    
        }
        finally
        {
            ledSpeed = prevLedSpeed;
        }
        return true;
    }

    static void sleep()
    {
        try
        {
            Thread.sleep(ledSpeed);
        }
        catch (InterruptedException e) {}
    }
}

